﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using WinSCP;
using System.IO;
using System.Data;

namespace BAMLFileTransfer
{
    public class FTPConn
    {
        //FTP host
        private string _host;
        //User name
        private string _userName;
        //password
        private string _password;
        //Port
        private string _port;
        //local file path
        public string _localPath;
        //server file path
        public string _serverPath;
        //protocol
        public int _protocol;

        public FTPConn(string host, string userName, string password)
        {
            _host = host;
            _userName = userName;
            _password = password;
        }
        public FTPConn(string host, string userName, string password, string localPath, string serverPath)
        {
            _host = host;
            _userName = userName;
            _password = password;


            _localPath = localPath;
            _serverPath = serverPath;
        }

        private int createFolder(string path, bool hidden = false)
        {
            try
            {
                //test if this folder already exists

                if (!Directory.Exists(path))
                {
                    DirectoryInfo di = Directory.CreateDirectory(path);
                    if (true == hidden)
                        di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
                }
                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return 1;
            }

        }
        public int renameFiles(string path)
        {
            DirectoryInfo dirInfo = new DirectoryInfo(path);
            FileInfo[] infos = dirInfo.GetFiles();


            foreach (FileInfo f in infos)
            {
                string newFileName = f.FullName;
                string timeStamp = newFileName.Substring(newFileName.Length - 14).Replace('.', '_');
                newFileName = newFileName.Substring(0, newFileName.Length - 15);
                int dotpos = newFileName.IndexOf('.');
                if (dotpos < 0)
                {
                    return 0;
                }
                newFileName = newFileName.Substring(0, dotpos) + "__" + timeStamp + newFileName.Substring(dotpos);

                string tempFileName = "";
                tempFileName = newFileName;
                int i = 1;
                while (File.Exists(tempFileName))
                {
                    tempFileName = newFileName.Insert(newFileName.IndexOf('.'), "(" + i.ToString() + ")");
                    i++;
                }

                if (tempFileName != newFileName)
                    newFileName = tempFileName;
                File.Move(f.FullName, newFileName);

            }
            return 0;
        }

        private int moveFiles(string sourcePath, string destPath)
        {
            try
            {
                if (!Directory.Exists(sourcePath))
                    throw new Exception("Source path does not exist");
                if (!Directory.Exists(destPath))
                    throw new Exception("Destination path does not exist");

                DirectoryInfo dirInfo = new DirectoryInfo(sourcePath);
                FileInfo[] infos = dirInfo.GetFiles();
                foreach (FileInfo f in infos)
                {
                    string newFileName = destPath + "\\" + f.Name;
                    string tempFileName = "";
                    tempFileName = newFileName;
                    int i = 1;
                    while (File.Exists(tempFileName))
                    {
                        tempFileName = newFileName.Insert(newFileName.IndexOf('.'), "(" + i.ToString() + ")");
                        i++;
                    }
                    if (tempFileName != newFileName)
                        newFileName = tempFileName;

                    File.Move(f.FullName, newFileName);
                }
                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return 1;
            }
        }
        public int deleteFiles(string path)
        {
            try
            {
                if (!Directory.Exists(path))
                    throw new Exception("Cannot delete all the files becuase there is no such directory");

                DirectoryInfo dirInfo = new DirectoryInfo(path);
                FileInfo[] infos = dirInfo.GetFiles();
                foreach (FileInfo f in infos)
                {
                    f.Delete();

                }

                return 0;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                return 1;
            }
        }


        public int connect()
        {
            try
            {
                SessionOptions sessionOptions = new SessionOptions
                {
                    Protocol = Protocol.Sftp,
                    HostName = _host,
                    UserName = _userName,
                    Password = _password,
                    SshHostKey = ConfigurationManager.AppSettings["hostkey"]
                };



                using (Session session = new Session())
                {
                    session.Open(sessionOptions);
 
                    Console.WriteLine("Createing 'temp' folder ......");
                    //Step 1: create 'temp' folder
                    string folderPath = _localPath + ConfigurationManager.AppSettings["tempFolderName"];
                    this.createFolder(folderPath, true);

                    //Step 2: fetch date from the server to the folder path
                    if (!Directory.Exists(folderPath))
                        throw new Exception("Local Path does not exists");

                    Console.WriteLine("Downloading files from server ......");
                    /*This code is used to list all the files on the server directory*/
                    RemoteDirectoryInfo directory = session.ListDirectory(this._serverPath);
                    foreach (RemoteFileInfo fileinfo in directory.Files)
                    {
                        if (fileinfo.Name != "." & fileinfo.Name != "..")
                            session.GetFiles(this._serverPath + fileinfo.Name, folderPath + fileinfo.Name, true).Check();
                    }


                    //Step 3: rename all the files by move the postfix to the file name 
                    Console.WriteLine("Processing downloaded files ......");
                    this.renameFiles(folderPath);

                    //Step 4: move file from 'temp' folder to the current date folder
                    Console.WriteLine("Saving downloaded files ......");
                    string todayFolder = DateTime.Now.AddDays(-1).ToString(@"yyyyMMdd");
                    string todayPath = _localPath + todayFolder;
                    this.createFolder(todayPath);
                    this.moveFiles(folderPath, _localPath + todayFolder +@"\");

                    //Step 5: delete 'temp' folder
                    Console.WriteLine("Finishing up ......");
                    this.deleteFiles(folderPath);
                    Directory.Delete(folderPath);
                    Console.WriteLine("Done!");

                    //Step 6: record the time of this download 
                    string cur = DateTime.Now.ToString(@"MM/dd/yyyy hh:mm:ss tt");
                    string settingFolder = _localPath + ConfigurationManager.AppSettings["settingFolderName"];
                    this.createFolder(settingFolder, true);
                    File.WriteAllText(settingFolder + "log.txt", cur);


                        
                    
                    return 0;
                }

            }
            catch (Exception e)
            {
                //write to the log file
                Console.WriteLine(e.ToString());
                throw;
            }
        }
    }
}
